package com.lin.utils;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.lin.customEnum.RecordStatus;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedisSerializerUtil {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    private final ObjectMapper mapper = new ObjectMapper();
    {
        /*
        Jackson 在尝试序列化或反序列化 `java.time.LocalDateTime` 类型时,
        默认不支持 Java 8 的 `LocalDateTime`, 需要注册JavaTimeModule支持
         */
        mapper.registerModule(new JavaTimeModule());
    }

    /**
     * 将对象序列化成json串, 存在则不修改, Redis中默认存放10分钟, 超时自动删除
     * @param key key
     * @param obj value
     * @param <T> 对象类型
     */
    public <T> void set(String key, T obj) throws JsonProcessingException {
        this.set(key, obj, 10, TimeUnit.MINUTES);
    }

    /**
     * 将对象序列化成json串, 并设置过期时间, 存在则不修改
     * @param key key
     * @param obj value
     * @param timeout 过期时间
     * @param timeUnit 时间单位
     * @param <T> 对象类型
     */
    public <T> void set(String key, T obj, long timeout, TimeUnit timeUnit) throws JsonProcessingException {
        String s = mapper.writeValueAsString(obj); // 将对象序列化成json串
        stringRedisTemplate.opsForValue().setIfAbsent(key, s, timeout, timeUnit);
    }

    /**
     * 将json串反序列化成对象
     * @param key key
     * @param clazz 对象类字节码
     * @return 对象
     */
    @SuppressWarnings("all")
    public <T> T get(String key, Class<T> clazz) throws JsonProcessingException {
        String s = stringRedisTemplate.opsForValue().get(key);
        // 如果Redis中没有指定key, 返回null
        if (s != null && !s.isBlank())
            return mapper.readValue(s, clazz);
        return null;
    }

    public <T> T get(String key, TypeReference<T> typeReference) throws JsonProcessingException {
        String s = stringRedisTemplate.opsForValue().get(key);
        if (s != null && !s.isBlank()) {
            return mapper.readValue(s, typeReference);
        }
        return null;
    }

    /**
     * 删除key
     * @param key key
     */
    public void delete(String... key) {
        for (String s : key) {
            stringRedisTemplate.delete(s);
        }
    }

}
